package com.sl.transport.repository.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.sl.transport.domain.OrganDTO;
import com.sl.transport.enums.OrganTypeEnum;
import com.sl.transport.repository.OrganRepository;
import org.neo4j.driver.types.Node;
import org.springframework.data.neo4j.core.Neo4jClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Component
public class OrganRepositoryImpl implements OrganRepository {

    @Resource
    private Neo4jClient neo4jClient;

    @Override
    public OrganDTO findByBid(Long bid) {
        return CollUtil.getFirst(this.findByBids(ListUtil.toList(bid)));
    }

    @Override
    public List<OrganDTO> findByBids(List<Long> bids) {
        String cypherQuery = StrUtil.format("MATCH (n) WHERE n.bid IN {} RETURN n", bids);
        return this.executeCypher(cypherQuery);
    }

    @Override
    public List<OrganDTO> findAll(String name) {
        //如果传入的name为空查询全部，否在按照name模糊查询
        name = StrUtil.removeAll(name, '\'', '"');
        String cypherQuery = StrUtil.isEmpty(name) ?
                "MATCH (n) RETURN n" :
                StrUtil.format("MATCH (n) WHERE n.name CONTAINS '{}' RETURN n", name);
        return this.executeCypher(cypherQuery);
    }

    private List<OrganDTO> executeCypher(String cypherQuery) {
        return ListUtil.toList(this.neo4jClient.query(cypherQuery)
                .fetchAs(OrganDTO.class)
                .mappedBy((typeSystem, record) -> {
                    Node node = record.get("n").asNode();
                    Map<String, Object> map = node.asMap();
                    OrganDTO organDTO = BeanUtil.toBean(map, OrganDTO.class);
                    //取第一个标签作为类型
                    organDTO.setType(OrganTypeEnum.valueOf(CollUtil.getFirst(node.labels())).getCode());
                    //查询出来的数据，x：经度，y：纬度
                    organDTO.setLatitude(BeanUtil.getProperty(map.get("location"), "y"));
                    organDTO.setLongitude(BeanUtil.getProperty(map.get("location"), "x"));
                    return organDTO;
                })
                .all());
    }
}
